package com.fast.inteceptor;

import cn.hutool.core.thread.threadlocal.NamedThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class AaMyInterceptor implements HandlerInterceptor {

    //NamedThreadLocal：Spring提供的一个命名的ThreadLocal实现。线程安全的，每进来一个请求都会创建一个单独的对象，其他用户不会收到影响
    //ThreadLocal，它是线程绑定的变量，提供线程局部变量（一个线程一个 ThreadLocal，A线程的ThreadLocal 只能看到A线程的 ThreadLocal，不能看到B线程的 ThreadLocal）
    //一个请求创建一个对象不会影响到其他请求，所以时间不会混乱
    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("StopWatch-StartTime");

    //控制器方法执行之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long beginTime = System.currentTimeMillis();//1、开始时间
        startTimeThreadLocal.set(beginTime);//线程绑定变量（该数据只有当前请求的线程可见）
        return true;//继续流程
    }

    //控制器方法执行以后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    //处理完视图和模型数据，渲染视图完毕之后执行afterCompletion()
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long endTime = System.currentTimeMillis();//2、结束时间
        long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量（开始时间）
        long consumeTime = endTime - beginTime;//3、消耗的时间

        System.out.println("开始时间："+beginTime);
        System.out.println("结束时间："+endTime);
        System.out.println("消耗时间："+consumeTime);
        if(consumeTime > 500) {//此处认为处理时间超过500毫秒的请求为慢请求
            //TODO 记录到日志文件 设置日志
            log.info(String.format("%s consume %d millis", request.getRequestURI(), consumeTime));
        } else {
            // 测试的时候由于请求时间未超过500，所以启用该代码
            //request.getRequestURI()：请求路径：/test/filter
            //consumeTime：销毁时间
            // 日志打印：/test/filter consume 13 millis
            log.info(String.format("%s consume %d millis", request.getRequestURI(), consumeTime));
        }
    }

}
